package com.genntii.examManager.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.genntii.examManager.common.exception.ExamNotFoundException;
import com.genntii.examManager.common.result.PageResult;
import com.genntii.examManager.domain.entity.*;
import com.genntii.examManager.domain.question.dto.ExamResult;
import com.genntii.examManager.domain.question.mongo.Vocabularies;
import com.genntii.examManager.domain.vo.PracticeRecordVO;
import com.genntii.examManager.mapper.*;
import com.genntii.examManager.service.PracticeRecordService;
import jakarta.annotation.Resource;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@Service
public class PracticeRecordServiceImpl extends ServiceImpl<PracticeRecordMapper, PracticeRecord> implements PracticeRecordService {

    @Resource
    private PracticeRecordMapper practiceRecordMapper;

    @Resource
    private PracticeMapper practiceMapper;

    @Resource
    private TeacherMapper teacherMapper;

    @Resource
    private MongoTemplate mongoTemplate;

    @Resource
    private CourseMapper courseMapper;

    @Override
    public ExamResult getPracticeResult(Long practiceRecordId) {
        if (practiceRecordMapper.selectById(practiceRecordId) == null){
            throw new ExamNotFoundException("考试记录不存在");
        }

        return mongoTemplate.findOne(new Query(new Criteria("_id").is(practiceRecordId)), ExamResult.class,"practiceUserResult");
    }

    @Override
    public PageResult<PracticeRecordVO> getPracticeHistory(Integer pageNum, Integer pageSize, Long userId) {
        ArrayList<PracticeRecord> practiceRecords = practiceRecordMapper.getPracticeHistory(userId, (pageNum - 1) * pageSize, pageSize);

        ArrayList<Long> examIds = new ArrayList<>();
        for (PracticeRecord practiceRecord:practiceRecords){
            examIds.add(practiceRecord.getPracticeId());
        }
        ArrayList<Practice> practices = practiceMapper.getPracticeBatch(examIds);
        Map<Long, Practice> practiceIdMap = new HashMap<>();
        for (Practice practice:practices){
            practiceIdMap.put(practice.getId(),practice);
        }
        ArrayList<Long> courseIds = new ArrayList<>();
        ArrayList<Long> teacherIds = new ArrayList<>();
        for (Practice practice:practices){
            courseIds.add(practice.getCourseId());
            teacherIds.add(practice.getTeacherId());
        }
        ArrayList<Course> courses = courseMapper.getCourseBatch(courseIds);
        ArrayList<Teacher> teachers = teacherMapper.getTacherBatch(teacherIds);

        Map<Long, Course> courseMap = new HashMap<>();
        Map<Long, Teacher> teacherMap = new HashMap<>();
        for (Teacher teacher : teachers){
            teacherMap.put(teacher.getId(),teacher);
        }
        for (Course course : courses){
            courseMap.put(course.getId(),course);
        }

        ArrayList<PracticeRecordVO> practiceRecordVOS = new ArrayList<>();
        for (PracticeRecord practiceRecord : practiceRecords){
            practiceRecordVOS.add(PracticeRecordVO.builder()
                    .id(practiceRecord.getId())
                    .practiceId(practiceRecord.getPracticeId())
                    .courseName(courseMap.get(practiceIdMap.get(practiceRecord.getPracticeId()).getCourseId()).getCourseName())
                    .teacherName(teacherMap.get(practiceIdMap.get(practiceRecord.getPracticeId()).getTeacherId()).getName())
                    .startTime(practiceIdMap.get(practiceRecord.getPracticeId()).getStartTime())
                    .commitTime(practiceRecord.getCommitTime())
                    .practiceName(practiceIdMap.get(practiceRecord.getPracticeId()).getPracticeName())
                    .build());
        }
        return PageResult.build(practiceRecordVOS, practiceRecordMapper.getPracticeHistoryTotal(userId));
    }

    @Override
    public void practiceCommit(ExamResult examResult, Long userId) {
        if (practiceMapper.selectById(examResult.getExamId()) == null){
            throw new ExamNotFoundException("未找到考试");
        }

        PracticeRecord practiceRecord;
        if (examResult.getTopicDTO().getVocabularyDTOS().isEmpty()){
            practiceRecord = practiceRecordMapper.selectByUserPractice(userId,examResult.getExamId());
            practiceRecord.setCommitTime(examResult.getCommitTime());
            practiceRecord.setStatus((byte) 1);
            practiceRecord.setScore(examResult.getBaseScore());
            practiceRecordMapper.updateById(practiceRecord);
        } else {
            practiceRecord = practiceRecordMapper.selectByUserPractice(userId,examResult.getExamId());
            practiceRecord.setCommitTime(examResult.getCommitTime());
            practiceRecord.setStatus((byte) 1);
            practiceRecordMapper.updateById(practiceRecord);

            mongoTemplate.insert(Vocabularies.builder()
                    ._id(practiceRecord.getId())
                    .vocabularyDTOS(examResult.getTopicDTO().getVocabularyDTOS()).build(),"practiceVocabulary");
        }

        examResult.setId(practiceRecord.getId());
        mongoTemplate.insert(examResult,"practiceUserResult");
    }
}
